package xyz.naokeziteng.data_structure;

/**
 * @author hawk
 * @date 2022/7/26
 * @desc 数组
 **/
public class Array<E> {

    private Object[] data;
    private int size;


    /**
     * 构造方法
     *
     * @param capacity 数组容量
     */
    public Array(int capacity) {
        data = new Object[capacity];
        size = 0;
    }

    /**
     * 默认容量10
     */
    public Array() {
        this(10);
    }

    /**
     * 返回元素个数
     *
     * @return 元素个数
     */
    public int getSize() {
        return this.size;
    }

    /**
     * 返回容量
     *
     * @return 容量
     */
    public int getCapacity() {
        return data.length;
    }

    /**
     * 向末尾添加元素
     *
     * @param e 元素
     */
    public void addLast(E e) {
        add(size, e);
    }

    /**
     * 向数组开头添加元素
     *
     * @param e 元素
     */
    public void addFirst(E e) {
        add(0, e);
    }

    /**
     * 添加元素
     *
     * @param index 下标
     * @param e     元素
     */
    public void add(int index, E e) {
        /*if (size == data.length) {
            throw new IllegalArgumentException("AddLast failed. Array is full.");
        }*/
        if (index < 0 || index > size) {
            throw new IllegalArgumentException("AddLast failed. Require index >=0 and index <=size.");
        }
        //元素向后移动
        //System.arraycopy(data, index, data, index + 1, size - index);
        for (int i = size - 1; i >= index; i--) {
            data[i + 1] = data[i];
        }
        data[index] = e;
        size++;
        if (size == data.length) {
            //扩容
            Object[] expansion = new Object[data.length * 2];
            System.arraycopy(data, 0, expansion, 0, data.length);
            data = expansion;
        }
    }


    /**
     * 获取指定下标元素
     *
     * @param index 下标
     * @return 元素
     */
    @SuppressWarnings("unchecked")
    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("Get failed. Index is illegal.");
        }
        return (E) data[index];
    }

    /**
     * 获取最后的元素
     *
     * @return 元素
     */
    public E getLast() {
        return get(size - 1);
    }

    public E getFirst() {
        return get(0);
    }

    /**
     * 修改指定下标元素
     *
     * @param index 下标
     * @param e     元素
     */
    public void set(int index, E e) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("update failed. Index is illegal.");
        }
        data[index] = e;
    }


    /**
     * 判断数组是否包含某个元素
     *
     * @param e 元素
     * @return 是否包含
     */
    public boolean contains(E e) {
        for (Object i : data) {
            if (i.equals(e)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 删除指定下标元素
     *
     * @param index 下标
     * @return 被删除的元素
     */
    @SuppressWarnings("unchecked")
    public E remove(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("remove failed. Index is illegal.");
        }
        E result = (E) data[index];
        for (int i = index + 1; i < size; i++) {
            data[i - 1] = data[i];
        }
        size--;
        return result;
    }

    /**
     * 删除最后的元素
     *
     * @return 元素
     */
    public E removeLast() {
        return remove(size - 1);
    }

    public E removeFirst() {
        return remove(0);
    }

    public boolean isEmpty() {
        return size == 0;
    }


    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("Array: size = %d , capacity = %d\n", size, data.length));
        sb.append("[");
        for (int i = 0; i < size; i++) {
            sb.append(data[i]);
            if (i != size - 1) {
                sb.append(", ");
            }
        }
        sb.append("]");
        return sb.toString();
    }
}
